package edu.washington.cs.workflow.analysis.guistructure.uievents;

import org.uispec4j.Panel;

import edu.washington.cs.workflow.analysis.guistructure.UIActionTracer;
import edu.washington.cs.workflow.analysis.guistructure.UIPos;
import edu.washington.cs.workflow.analysis.guistructure.uievents.UIEvent.WINDOW;
import edu.washington.cs.workflow.util.Utils;

public abstract class AbstractUIEvent implements UIEvent {

	protected Panel currentPanel = null;
	private WINDOW windowFlag = null; /** for replay */
	
	protected UIPos uipos = null;
	
	protected UIEvent aboveEvent = null;
	
	/**
	 * if the current UI event is on a different dialog than the main dialog
	 * */
	@Override
	public void setAboveEvent(UIEvent e) {
		Utils.checkNotNull(e);
		this.aboveEvent = e;
	}
	
	@Override
	public Panel getCurrentPanel() {
		return this.currentPanel;
	}
	
	public UIPos getUIComponentPos() {
		return this.uipos;
	}
	
	public void setUIComponentPos(UIPos pos) {
		Utils.checkNotNull(pos);
		Utils.checkTrue(uipos == null);
		this.uipos = pos;
	}
	
	@Override
	public UIEventOutcome fireEvent() {
		//the action to execute
		String actionDesc = this.toString();
		if(this.aboveEvent != null) {
			actionDesc = this.aboveEvent.toString() + " --> " + actionDesc;
		}
		//track the executed action
		UIActionTracer.tracer.traceAction(actionDesc);
		Utils.checkNotNull(this.getWindowFlag(), "This event: " + this.toString());
		UIEventOutcome outcome = fireEventInternal();
		return outcome;
		
	}
	
	@Override
	public abstract boolean canFireEvent();
	
	protected abstract WINDOW probeWindowInfoInternal();
	
	protected abstract UIEventOutcome fireEventInternal();
	
	public void setCurrentPanel(Panel p) {
		this.currentPanel = p;
	}
	
	@Override
	public WINDOW probeWindowInfo() {
		String actionDesc = this.toString();
		UIActionTracer.tracer.traceAction(actionDesc);
		WINDOW w = probeWindowInfoInternal();
		this.setWindowFlag(w);
		return w;
	}
	
	
	@Override
	final public void setWindowFlag(WINDOW win) {
		Utils.checkNotNull(win, "Current event: " + this.toString());
		Utils.checkTrue(this.windowFlag == null);
		this.windowFlag = win;
	}
	
	@Override
	final public WINDOW getWindowFlag() {
		return this.windowFlag;
	}
	
	@Override
	public String getDescription() {
		return toString();
	}
	
	@Override
	public boolean isCurrentPanelClosed() {
		return !this.getCurrentPanel().isVisible().isTrue();
	}
}
